// 定义Promise类（ES6标准）
class Promise{
    // 构造方法，初始化Promise
    constructor(excutor){
        this.PromiseState = "pending";
        this.PromiseResult = undefined;
        this.callbacks = []; // 用于存放待执行函数的属性

        // 声明成功处理内函数
        const success = (value) => {
            // 判断状态PromiseState是否已经不是pending，则退出
            if(this.PromiseState != "pending") return;
            this.PromiseState = "fulfilled";
            this.PromiseResult = value;
            // 执行callbacks属性里面保存下来没有执行的回调（异步导致）
            this.callbacks.forEach(item => {
                // 执行成功的回调方法ok
                item.ok();
            });
        }
        const error = (reason) => {
            // 判断状态PromiseState是否已经不是pending，则退出
            if(this.PromiseState != "pending") return;
            this.PromiseState = "rejected";
            this.PromiseResult = reason;
            // 执行callbacks属性里面保存下来没有执行的回调（异步导致）
            this.callbacks.forEach(item => {
                // 执行失败的回调方法ng
                item.ng();
            });
        } 
        try {
            // 执行excutor函数，要求传递两个函数类型参数
            excutor(success, error);
        } catch (e) {
            error(e);
        }
    }

    // then方法
    then(onResolved, onRejected){
        return new Promise((resolve, reject) => {
            // 声明一个函数 『handle 处理的意思』
            let handle = (type) => {
                try{
                    let res = type(this.PromiseResult);
                    // 判断res结果是否是一个Promise
                    if(res instanceof Promise){
                        // 将当前res的promise状态添加到新的Promise
                        res.then(v => {
                            resolve(v);
                        },r => {
                            reject(r);
                        });
                    } else {
                        // 若返回值不是Promise对象，就直接返回一个成功的，值为返回值的promise
                        resolve(res);
                    }
                }catch(e){
                    reject(e);
                }
            }
            // 判断PromiseState状态值来执行对应的参数函数
            if(this.PromiseState === "fulfilled"){
                handle(onResolved);
            }
            if(this.PromiseState === "rejected"){
                handle(onRejected);
            }
            // 判断PromiseState状态值为pending时，先将两个参数函数收取起来，等待改变状态是再次执行
            if(this.PromiseState === "pending"){
                // 将当前待调用的回调函数保存起来
                this.callbacks.push({
                    // 状态成功时调用方法
                    ok:function(value){
                        handle(onResolved);
                    },
                    // 状态失败是调用方法
                    ng:function(reason){
                        handle(onRejected);
                    }
                })
            }
            
        });    
    } 

    // catch方法
    catch(onRejected){
        return this.then(undefined,onRejected);
    }
    
    // resolve方法（静态方法）
    static resolve(value){
        return new Promise((resolve,reject) => {
            // 判断value结果是否是一个Promise
            if(value instanceof Promise){
                // 将当前res的promise状态添加到新的Promise
                value.then(v => {
                    resolve(v);
                },r => {
                    reject(r);
                });
            }else{
                resolve(value);
            }
        })
    }

    // reject方法（静态方法）
    static reject(reason){
        return new Promise((resolve,reject) => {
            reject(reason);
        })
    }

    // all 方法
    static all(promiseArr){
        // 声明一个数组
        let data = [];
        // 声明计数器
        //let count = 0;
        // 返回值 promise 对象
        return new Promise((resolve, reject) => {
            // 遍历
            promiseArr.forEach((item, index) => {
                // 调用 then 方法
                item.then(v=>{
                    // 当所有的 promise 对象状态都为成功的时候, 
                    // 才能调用 resolve 函数, 并设置成功的结果值
                    // data.push(v);
                    data[index] = v; // data[2] = 'Yeah'
                    // 成功一个自增
                // count++;
                    // 判断长度是否已满
                    if((index+1) === promiseArr.length){
                        resolve(data);
                    }
                }, r=>{
                    //如果当前 promise 失败, 则修改 all 返回 promise 状态为失败
                    reject(r);
                })
            })
        });
    } 

    // 添加 race 方法
    static race(promiseArr){
        return new Promise((resolve, reject) => {
            //遍历数组
            promiseArr.forEach(item => {
                item.then(v => {
                    resolve(v);
                }, r => {
                    reject(r);
                })
            });
        })
    }

}